package br.com.busgps.crawler;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.com.busgps.bean.Bus;
import br.com.busgps.bean.Location;
import br.com.busgps.dao.impl.BusDAOImpl;
import br.com.busgps.dao.impl.LocationDAOImpl;
import br.com.busgps.mapper.json.Result;
import br.com.busgps.util.Constants;
import br.com.busgps.util.ResultConnection;

import com.google.gson.JsonSyntaxException;

/**
*
* <b>Descricao da Classe:</b><br> 
* 
* Classe responsavel por trazer todas as informacoes dos onibus no servidor da
* prefeitura.
*
* @author rodrigo.bacellar
* @since 11/11/2014
*
*/
public class CrawlerBusGps implements Job
{

    private static Logger logger = LoggerFactory.getLogger(CrawlerBusGps.class);

    public void execute(JobExecutionContext arg0) throws JobExecutionException
    {
        logger.info("Job Started - " + getClass().getSimpleName() + "");

        try
        {
            StringBuilder sb = new StringBuilder(Constants.BASE_URL);
            sb.append(Constants.ALL_BUSES);

            /** Obtem os dados do servidor */
            Result result = ResultConnection.getData(sb.toString());

            if (insert(result))
            {
                logger.info("SUCESSO!");
            }
            else
            {
                logger.error("FALHA!");
            }
        }
        catch (MalformedURLException e)
        {
            logger.error("Erro no formato da URL. " + e);
        }
        catch (IOException e)
        {
            logger.error("Erro de I/O na conexao. " + e);
        }
        catch (JsonSyntaxException e)
        {
            logger.error("Erro de formatacao no json. " + e);
        }

        logger.info("Job Finished - " + getClass().getSimpleName() + "");
    }

    /**
     * Obtem a lista de onibus.
     * 
     * @param result
     * @return
     */
    private List<Location> resultToBus(Result result)
    {
        List<Location> locs = new ArrayList<Location>();

        for (List<String> item : result.getDATA())
        {
            String line = item.get(2);

            /** Tem onibus com a linha vazia ou com numero errado (2 digitos) */
            if (!"".equalsIgnoreCase(line) || line.length() > 2)
            {
                Location loc = new Location();

                /** Data */
                loc.setDate(new Date());

                /** Latitude */
                loc.setLatitude(Float.valueOf(item.get(3)));

                /** Longitude */
                loc.setLongitude(Float.valueOf(item.get(4)));

                /** Speed */
                loc.setSpeed(Float.valueOf(item.get(3)));

                Bus bus = new Bus();

                /** Ordem */
                bus.setOrdem(item.get(1));

                /** Linha */
                bus.setNumber(item.get(2));

                loc.setBus(bus);

                locs.add(loc);
            }
        }

        return locs;
    }

    /**
     * @param result
     * @return
     */
    private boolean insert(Result result)
    {
        List<Location> locs = resultToBus(result);

        BusDAOImpl busDAOImpl = new BusDAOImpl();

        LocationDAOImpl locDAOImpl = new LocationDAOImpl();

        for (Location loc : locs)
        {
            /** Buscar a ordem do onibus. */
            Bus bus = busDAOImpl.getByOrdem(loc.getBus().getOrdem());

            Long busId = 0L;

            if (bus == null)
            {
                busId = busDAOImpl.insert(bus);
            }
            else
            {
                busId = bus.getId();
            }

            return locDAOImpl.insert(loc, busId);
        }

        return true;
    }

}
